package com.silence.springboot.dao;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.silence.springboot.dto.BookBaseJoinAuthorDto;
import com.silence.springboot.dto.BookStatusAdminDto;
import com.silence.springboot.dto.BookStatusJoinAuthorDto;
import com.silence.springboot.entity.BookBaseEntity;
import com.silence.springboot.mapper.BookBaseMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

import static com.silence.springboot.entity.table.AuthorInfoEntityTableDef.AUTHOR_INFO_ENTITY;
import static com.silence.springboot.entity.table.BookBaseEntityTableDef.BOOK_BASE_ENTITY;

/**
 * 作者信息表 数据访问层实现。
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class BookBaseDao {

    /**
     * 作者信息表 Mapper 接口
     */
    private final BookBaseMapper bookBaseMapper;

    /**
     * 新建入库
     *
     * @param entity 作者信息表实体类
     */
    public void insertBookByQuery(BookBaseEntity entity) {
        // 向数据库插入信息
        bookBaseMapper.insertSelective(entity);

    }

    /**
     * 根据图书编号查询图书信息表实体类
     *
     * @param id 图书编号
     * @return 图书信息表实体类
     */
    public BookBaseEntity selectBookByQuery(Long id) {
        // 查询数据库中的图书信息
        return bookBaseMapper.selectOneByQuery(QueryWrapper.create()
                .select()
                .from(BOOK_BASE_ENTITY)
                .where(BOOK_BASE_ENTITY.ID.eq(id)));

    }

    /**
     * 更新信息
     *
     * @param entity 图书信息表实体类
     */
    public void updateBookByQuery(BookBaseEntity entity) {
        bookBaseMapper.update(entity);
    }

    /**
     * 分页查询图书信息
     *
     * @param pageNum    页码
     * @param pageSize   每页数量
     * @param bookName   图书名称
     * @param authorName 作者名称
     * @return 图书信息
     */
    public Page<BookBaseJoinAuthorDto> pageBookBaseInfoByQuery(Integer pageNum, Integer pageSize, String bookName, String authorName) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(BOOK_BASE_ENTITY.ALL_COLUMNS)
                .select(AUTHOR_INFO_ENTITY.BOOK_AUTHOR_NAME,
                        AUTHOR_INFO_ENTITY.AUTHOR_EMAIL,
                        AUTHOR_INFO_ENTITY.AUTHOR_PRESS,
                        AUTHOR_INFO_ENTITY.AUTHOR_TELEPHONE)
                .from(BOOK_BASE_ENTITY)
                .leftJoin(AUTHOR_INFO_ENTITY)
                .on(BOOK_BASE_ENTITY.BOOK_AUTHOR_ID.eq(AUTHOR_INFO_ENTITY.ID))
                .where(BOOK_BASE_ENTITY.BOOK_NAME.like(bookName, StringUtils::isNotBlank))
                .where(AUTHOR_INFO_ENTITY.BOOK_AUTHOR_NAME.like(authorName, StringUtils::isNotBlank));
        return bookBaseMapper.paginateAs(pageNum, pageSize, queryWrapper, BookBaseJoinAuthorDto.class);
    }

    /**
     * 删除图书信息
     *
     * @param id 主键
     */
    public void deleteBook(long id) {
        bookBaseMapper.deleteById(id);
    }

    /**
     * 查询所有图书信息
     *
     * @return 所有图书信息
     */
    public List<BookBaseEntity> selectAll() {
        return bookBaseMapper.selectAll();
    }

    /**
     * 借书
     *
     * @param id         图书id
     * @param borrowName 借书人
     */
    public void borrowBook(String id, String borrowName) {
        UpdateChain.of(BookBaseEntity.class)
                .from(BOOK_BASE_ENTITY)
                .set(BookBaseEntity::getBorrowBookName, borrowName)
                .set(BookBaseEntity::getBorrowTime, LocalDateTime.now())
                .set(BookBaseEntity::getReturnBookName, "")
                .set(BookBaseEntity::getReturnTime, null)
                .set(BookBaseEntity::getBookStatus, "1")
                .where(BookBaseEntity::getId).eq(Long.parseLong(id))
                .update();
    }

    /**
     * 还书
     *
     * @param id         图书id
     * @param returnName 还书人
     */
    public void returnBook(String id, String returnName) {
        UpdateChain.of(BookBaseEntity.class)
                .from(BOOK_BASE_ENTITY)
                .set(BookBaseEntity::getReturnBookName, returnName)
                .set(BookBaseEntity::getReturnTime, LocalDateTime.now())
                .set(BookBaseEntity::getBorrowBookName, "")
                .set(BookBaseEntity::getBorrowTime, null)
                .set(BookBaseEntity::getBookStatus, "3")
                .where(BookBaseEntity::getId).eq(Long.parseLong(id))
                .update();
    }

    /**
     * 分页查询图书状态
     *
     * @param pageNumber 页码
     * @param pageSize   每页数量
     * @param name       借阅人
     * @param bookName   图书名称
     * @param authorName 作者名称
     * @return 图书状态
     */
    public Page<BookStatusJoinAuthorDto> pageBookStatus(Integer pageNumber, Integer pageSize, String name, String bookName, String authorName) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(BOOK_BASE_ENTITY.ALL_COLUMNS)
                .select(AUTHOR_INFO_ENTITY.BOOK_AUTHOR_NAME)
                .from(BOOK_BASE_ENTITY)
                .leftJoin(AUTHOR_INFO_ENTITY)
                .on(BOOK_BASE_ENTITY.BOOK_AUTHOR_ID.eq(AUTHOR_INFO_ENTITY.ID))
                .where(BOOK_BASE_ENTITY.BOOK_NAME.like(bookName, StringUtils::isNotBlank))
                .and(AUTHOR_INFO_ENTITY.BOOK_AUTHOR_NAME.like(authorName, StringUtils::isNotBlank))
                .and(BOOK_BASE_ENTITY.BORROW_BOOK_NAME.eq(name).or(BOOK_BASE_ENTITY.RETURN_BOOK_NAME.eq(name)))
                .and(BOOK_BASE_ENTITY.BOOK_STATUS.in("1", "2", "3"));
        return bookBaseMapper.paginateAs(pageNumber, pageSize, queryWrapper, BookStatusJoinAuthorDto.class);
    }

    /**
     * 分页查询图书状态
     *
     * @param pageNumber     页码
     * @param pageSize       每页数量
     * @param bookName       图书名称
     * @param bookAuthorName 作者名称
     * @return 图书状态
     */
    public Page<BookStatusAdminDto> pageBookStatus(Integer pageNumber, Integer pageSize, String bookName, String bookAuthorName) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(BOOK_BASE_ENTITY.ALL_COLUMNS)
                .select(AUTHOR_INFO_ENTITY.BOOK_AUTHOR_NAME)
                .from(BOOK_BASE_ENTITY)
                .leftJoin(AUTHOR_INFO_ENTITY)
                .on(BOOK_BASE_ENTITY.BOOK_AUTHOR_ID.eq(AUTHOR_INFO_ENTITY.ID))
                .where(BOOK_BASE_ENTITY.BOOK_NAME.like(bookName, StringUtils::isNotBlank))
                .and(AUTHOR_INFO_ENTITY.BOOK_AUTHOR_NAME.like(bookAuthorName, StringUtils::isNotBlank))
                .and(BOOK_BASE_ENTITY.BOOK_STATUS.in("1", "3"));
        return bookBaseMapper.paginateAs(pageNumber, pageSize, queryWrapper, BookStatusAdminDto.class);
    }

    /**
     * 管理员同意借书或还书
     *
     * @param id 图书id
     */
    public void updateAgreeBorrowBookStatus(long id) {
        UpdateChain.of(BookBaseEntity.class)
                .from(BOOK_BASE_ENTITY)
                .set(BookBaseEntity::getBookStatus, "2")
                .set(BookBaseEntity::getBorrowTime, LocalDateTime.now())
                .where(BookBaseEntity::getId).eq(id)
                .update();
    }

    /**
     * 管理员同意借书或还书
     *
     * @param id 图书id
     */
    public void updateAgreeReturnBookStatus(long id) {
        UpdateChain.of(BookBaseEntity.class)
                .from(BOOK_BASE_ENTITY)
                .set(BookBaseEntity::getBookStatus, "0")
                .set(BookBaseEntity::getReturnTime, null)
                .set(BookBaseEntity::getBorrowBookName, "")
                .set(BookBaseEntity::getBorrowTime, null)
                .set(BookBaseEntity::getReturnBookName, "")
                .where(BookBaseEntity::getId).eq(id)
                .update();
    }

    /**
     * 管理员拒绝借书或还书
     *
     * @param id 图书id
     */
    public void updateRefuseBorrowBookStatus(long id) {
        UpdateChain.of(BookBaseEntity.class)
                .from(BOOK_BASE_ENTITY)
                .set(BookBaseEntity::getBookStatus, "0")
                .set(BookBaseEntity::getReturnTime, null)
                .set(BookBaseEntity::getBorrowBookName, "")
                .set(BookBaseEntity::getBorrowTime, null)
                .set(BookBaseEntity::getReturnBookName, "")
                .where(BookBaseEntity::getId).eq(id)
                .update();
    }

    /**
     * 管理员拒绝借书或还书
     *
     * @param id 图书id
     */
    public void updateRefuseReturnBookStatus(long id, String borrowBookName, LocalDateTime borrowTime) {
        UpdateChain.of(BookBaseEntity.class)
                .from(BOOK_BASE_ENTITY)
                .set(BookBaseEntity::getBookStatus, "2")
                .set(BookBaseEntity::getBorrowBookName, borrowBookName)
                .set(BookBaseEntity::getBorrowTime, borrowTime)
                .set(BookBaseEntity::getReturnBookName, "")
                .set(BookBaseEntity::getReturnTime, null)
                .where(BookBaseEntity::getId).eq(id)
                .update();
    }
}

